﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGourd.Core.Runners;
using NGourd.Core.Features;
using System.Reflection;
using NGourd.Core.Plans;

using NGourd.Core.Reports;

namespace NGourd.Core
{
    public class Runner
    {
        private readonly FeatureLibrary Features = new FeatureLibrary();
        private readonly StepLibrary Steps = new StepLibrary();
        private readonly IConfiguration Configuration;
        private readonly Librarian Librarian;

        public Runner(IConfiguration configuration)
        {
            Configuration = configuration;
            Librarian = new Librarian(Features, Steps);
            foreach (var assembly in Configuration.Assemblies)
                Librarian.AddAssemblyToLibraries(assembly);
            foreach (var file in Configuration.FeatureFiles)
                Librarian.AddFeatureFileToLibrary(file);
        }

        public bool Run()
        {
            var featuresForRun = Configuration.FeatureSet.Select(f => Features.GetFeature(f)).ToArray();
            if (featuresForRun.Length == 0)
                featuresForRun = Features.DefinedFeatures.Select(f => Features.GetFeature(f)).ToArray();

            var plan = new PlanBuilder(Steps).FormulatePlanForFeatureSet(featuresForRun);
            var report = plan.Execute(Configuration.IsDryRun);

            foreach (IReporter reporter in Configuration.Reporters)
                reporter.PrintReport(report);

            return report.Flatten().All(x => x.Status == ReportStatus.PASSED);
        }
    }
}
